package com.xusheng.cli.controller.proxy;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xusheng.cli.common.base.MyPage;
import com.xusheng.cli.common.base.Result;
import com.xusheng.cli.common.validation.Save;
import com.xusheng.cli.common.validation.Update;
import com.xusheng.cli.entity.backAgentModule.BackAgent;
import com.xusheng.cli.entity.backAgentModule.BackAgentUpdatePsd;
import com.xusheng.cli.entity.bankCardModule.BankCard;
import com.xusheng.cli.entity.frontUserModule.FrontUser;
import com.xusheng.cli.entity.rechargeModule.Recharge;
import com.xusheng.cli.entity.withdrawModule.Withdraw;
import com.xusheng.cli.service.*;
import com.xusheng.cli.tools.CurrentProxyUserUtil;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 代理商信息表(BackAgent)表控制层
 *
 * @author whr
 * @since 2024-03-19 17:56:47
 */
@Validated
@RestController
@RequestMapping("/proxy/v1/backAgent")
public class BackAgentController {
    /**
     * 服务对象
     */
    @Resource
    private BackAgentService backAgentService;
    @Resource
    private FrontUserService frontUserService;
    @Resource
    private RechargeService rechargeService;
    @Resource
    private WithdrawService withdrawService;
    @Resource
    private BankCardService bankCardService;

    /**
     * 查询所有数据
     *
     * @param backAgent 查询实体
     * @return 所有数据
     * @author whr
     * @since 2024-03-19 17:56:47
     */
    @GetMapping("queryAll")
    public Result<List<BackAgent>> queryAll(BackAgent backAgent) {
        return Result.success(backAgentService.list(new QueryWrapper<>(backAgent)));
    }

    /**
     * 分页查询所有数据
     *
     * @param page      分页对象
     * @param backAgent 查询实体
     * @return 所有数据
     * @author whr
     * @since 2024-03-19 17:56:47
     */
    @GetMapping("queryByPage")
    public Result<MyPage<BackAgent>> queryByPage(MyPage<BackAgent> page, BackAgent backAgent) {
        MyPage<BackAgent> myPage = backAgentService.page(page, new LambdaQueryWrapper<>(new BackAgent())
                .eq(BackAgent::getParentId, CurrentProxyUserUtil.getUserId())
                .like(StrUtil.isNotBlank(backAgent.getName()), BackAgent::getName, backAgent.getName())
                .like(StrUtil.isNotBlank(backAgent.getAccount()), BackAgent::getAccount, backAgent.getAccount()));
        for (BackAgent b : myPage.getRecords()) {
            BackAgent backAgentParent = backAgentService.getById(b.getParentId());
            if (backAgentParent != null) {
                b.setParentName(backAgentParent.getName());
                b.setParentRate(backAgentParent.getCommissionRate());
            }
        }
        return Result.success(myPage);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     * @author whr
     * @since 2024-03-19 17:56:47
     */
    @GetMapping("queryOne/{id}")
    public Result<BackAgent> selectOne(@PathVariable Serializable id) {
        return Result.success(backAgentService.getById(id));
    }

    /**
     * 新增数据
     *
     * @param backAgent 实体对象
     * @return 新增结果
     * @author whr
     * @since 2024-03-19 17:56:47
     */
    @PostMapping("insert")
    public Result<Object> insert(@Validated(Save.class) @RequestBody BackAgent backAgent) {
        long count = backAgentService.lambdaQuery()
                .eq(BackAgent::getAccount, backAgent.getAccount())
                .count();
        if (count > 0) {
            return Result.error("账号名已存在");
        }
        BackAgent parent = backAgentService.getById(CurrentProxyUserUtil.getUserId());
        // 获取上级
        Double rate = parent.getCommissionRate();
        if (rate < backAgent.getCommissionRate()) {
            return Result.error("费率无法大于上一级代理");
        }
        // 获取自身代理等级
        Integer level = parent.getLevel();
        backAgent.setLevel(level + 1);
        backAgent.setPassingTime(new Date());
        backAgent.setParentId(CurrentProxyUserUtil.getUserId());
        backAgent.setState(1);
        backAgent.setPassword(DigestUtil.bcrypt(backAgent.getPassword()));
        return Result.isSuccess(backAgentService.save(backAgent));
    }

    /**
     * 修改数据
     *
     * @param backAgent 实体对象
     * @return 修改结果
     * @author whr
     * @since 2024-03-19 17:56:47
     */
    @PutMapping("update")
    public Result<Object> update(@Validated(Update.class) @RequestBody BackAgent backAgent) {
        return Result.isSuccess(backAgentService.updateById(backAgent));
    }

    /**
     * 修改密码
     *
     * @param backAgent
     * @return
     */
    @PutMapping("updatePassword")
    public Result<Object> updatePassword(@Validated(Update.class) @RequestBody BackAgentUpdatePsd backAgent) {
        return Result.isSuccess(backAgentService.updatePassword(backAgent));
    }

    /**
     * 删除单条数据
     *
     * @param id 主键
     * @return 删除结果
     * @author whr
     * @since 2024-03-19 17:56:47
     */
    @DeleteMapping("delete/{id}")
    public Result<Object> delete(@PathVariable Long id) {
        BackAgent backAgent = backAgentService.getById(id);
        // 获取代理下的用户
//        frontUserService.removeProxyId(id);
//        return Result.isSuccess(backAgentService.removeById(backAgent));
        backAgentService.deleteHosts(backAgent);
        deleteProxyAndUser(backAgent);
        return Result.success();
    }

    @Transactional
    public void deleteProxyAndUser(BackAgent backAgent) {
        // 获取代理下的用户
        frontUserService.removeProxyId(backAgent.getId());
        backAgentService.removeById(backAgent);
        // 获取下级代理
        List<BackAgent> proxyList = backAgentService.lambdaQuery().eq(BackAgent::getParentId, backAgent.getId()).list();
        for (BackAgent proxy : proxyList) {
            deleteProxyAndUser(proxy);
        }
    }

    /**
     * 批量删除数据
     *
     * @param idList 主键结合
     * @return 删除结果
     * @author whr
     * @since 2024-03-19 17:56:47
     */
    @DeleteMapping("batchDelete")
    public Result<Object> batchDelete(@Validated @Size(min = 1, message = "缺少删除所需的id") @RequestParam("idList") List<Long> idList) {
        return Result.isSuccess(backAgentService.batchDelete(idList, new BackAgent()));
    }

    @GetMapping("getInfo")
    public Result<BackAgent> getInfo() {
        return Result.success(backAgentService.getById(CurrentProxyUserUtil.getUserId()));
    }

    @GetMapping("statistics")
    public Result<Map<String, Object>> getStatistics() {
        List<FrontUser> list = frontUserService.lambdaQuery().eq(FrontUser::getProxyId, CurrentProxyUserUtil.getUserId()).list();
        List<Long> ids = list.stream().map(frontUser -> frontUser.getId()).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        if (ids.size() > 0) {
            // 玩家量
            int playerCount = list.size();
            // 今日订单量
            DateTime beginDate = DateUtil.beginOfDay(new Date());
            DateTime endDate = DateUtil.endOfDay(new Date());
            List<Recharge> todayOrder = rechargeService.lambdaQuery()
                    .ge(Recharge::getCreateTime, beginDate)
                    .le(Recharge::getCreateTime, endDate)
                    .in(Recharge::getPlayerId, ids).list();
            int todayOrderCount = todayOrder.size();
            //总订单量
            Long orderCount = rechargeService.lambdaQuery()
                    .in(Recharge::getPlayerId, ids).count();
            //今日分层
            BackAgent backAgent = backAgentService.getById(CurrentProxyUserUtil.getUserId());
            BigDecimal income = BigDecimal.ZERO;
            Integer level = backAgent.getLevel();
            if (level == 1) {
                income = todayOrder.stream().collect(Collectors.reducing(BigDecimal.ZERO, Recharge::getProxyOneIncome, (i, j) -> i.add(j)));
            } else if (level == 2) {
                income = todayOrder.stream().collect(Collectors.reducing(BigDecimal.ZERO, Recharge::getProxyTwoIncome, (i, j) -> i.add(j)));
            } else if (level == 3) {
                income = todayOrder.stream().collect(Collectors.reducing(BigDecimal.ZERO, Recharge::getProxyThreeIncome, (i, j) -> i.add(j)));
            }
            //余额
            BigDecimal balance = backAgent.getBalance();
            map.put("playerCount", playerCount);
            map.put("todayOrderCount", todayOrderCount);
            map.put("orderCount", orderCount);
            map.put("income", income);
            map.put("balance", balance == null ? 0 : balance);
        } else {
            map.put("playerCount", 0);
            map.put("todayOrderCount", 0);
            map.put("orderCount", 0);
            map.put("income", 0);
            map.put("balance", 0);
        }
        return Result.success(map);
    }

    /**
     * 提现
     *
     * @param withdraw
     * @return
     */
    @PostMapping("withdraw")
    @Transactional
    public Result<Object> withdraw(@RequestBody Withdraw withdraw) {
        BackAgent backAgent = backAgentService.getById(CurrentProxyUserUtil.getUserId());
        if (withdraw.getAmount().compareTo(backAgent.getBalance() == null ? BigDecimal.ZERO : backAgent.getBalance()) > 0) {
            return Result.error("提现金额大于余额，无法提现");
        }
        withdraw.setUserId(CurrentProxyUserUtil.getUserId());
        withdraw.setState(1);
        withdraw.setType(1);
        // 获取银行卡信息
        BankCard bankInfo = bankCardService.lambdaQuery()
                .eq(BankCard::getOwnerId, CurrentProxyUserUtil.getUserId())
                .eq(BankCard::getCardDefault, true)
                .one();
        withdraw.setAccount(bankInfo.getCardNo());
        withdraw.setAccountType(2);
        withdraw.setBankName(bankInfo.getBankName());
        withdraw.setBankAccountName(bankInfo.getName());
        withdraw.setIdCard(bankInfo.getIdCard());
        withdraw.setPhone(bankInfo.getMobile());
        withdraw.setChannel(1);
        // 更新余额
        backAgent.setBalance(backAgent.getBalance().subtract(withdraw.getAmount()));
        backAgentService.updateById(backAgent);
        return Result.isSuccess(withdrawService.save(withdraw));
    }
}

